import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store' // 引入vuex store实例
import router from '@/router'
import { getTokenTime } from '@/utils/auth.js'
// 定义过期时间(时*分*秒*1000)
const timeOut = 2 * 60 * 60 * 1000
// 过期时间测试
// const timeOut = 10 * 1000

const request = axios.create({
  // baseURL: 'http://localhost:8083/api',
  // 动态绑定开发环境和生产环境的请求基准地址，通过process.env可以访问到环境变量
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 3000
})

// ^请求拦截器
request.interceptors.request.use((config) => {
  // config每次的请求配置
  // 配置请求头,在这个位置需要统一的去注入token
  const token = store.state.user.token
  if (token) {
    // 判断token是否过期
    if (isTimeOut()) {
      // 代表过期了,执行退出
      store.commit('user/logout')
      // 跳转到登录页
      router.push('/login')
      return Promise.reject(new Error('token超时了'))
    }
    // 如果token存在 注入token
    config.headers.Authorization = `Bearer ${token}`
  }
  return config // 必须返回配置
})

// ^响应拦截器
// 内部有两个回调，一个成功的回调，一个失败的回调
request.interceptors.response.use(
  // 成功的回调
  (res) => {
    // console.log(res)
    const { success, message, data } = res.data
    // 要根据success的成功与否决定下面的操作
    if (success) {
      return data
    } else {
      // ^业务错误
      // 提示错误消息
      Message.error(message)
      // 不能这么写 return Promise.reject(err)，要new Error()创建一个错误对象
      // 返回执行错误 让当前的执行链跳出成功 直接进入 catch
      return Promise.reject(new Error(message))
    }
  },
  // 失败的回调
  (err) => {
    // ^请求错误
    console.dir(err)
    if (err.response && err.response.status === 401) {
      Message.error('登录失效')
      // 代表过期了,执行退出
      store.commit('user/logout')
      // 跳转到登录页
      router.push('/login')
    } else {
      // 提示错误信息
      Message.error(err.message)
    }
    // Message.error(err.message)
    // 返回执行错误 让当前的执行链跳出成功 直接进入 catch
    return Promise.reject(err)
  }
)

// 封装token过期
function isTimeOut() {
  // 获取现在的时间
  const nowTime = Date.now()
  // 获取存储的过期时间
  const tokenTime = getTokenTime()
  const time = nowTime - tokenTime
  return time >= timeOut
}

export default request
